﻿using System.Collections.Generic;
using System.Net.Sockets;

//------------------------------------------------------------
// shaco Framework
// Copyright © 2017-2021 chang.liu All rights reserved.
// Feedback: 449612236@qq.com
//------------------------------------------------------------

namespace shaco.Base.Net
{
    /// <summary>
    /// 网络客户端接口
    /// </summary>
    public interface IClient : IGameInstance
    {
        /// <summary>
        /// 连接网络超时回调时间
        /// </summary>
        float connectTimeoutSeconds { get; }

        /// <summary>
        /// 发送消息网络超时回调时间
        /// </summary>
        float sendTimeoutSeconds { get; }

        /// <summary>
        /// 接收消息网络超时回调时间
        /// </summary>
        float receiveTimeoutSeconds { get; }
        
        /// <summary>
        /// 最大网络重联次数
        /// </summary>
        int maxReconnectTimes { get; }

        /// <summary>
        /// 连接网络
        /// <param name="host">主机地址</param>
        /// <param name="port">主机端口号</param>
        /// <param name="callback">连接结果回调(true:成功 false:失败)</param>
        /// </summary>
        void Connect(string host, int port, System.Action<bool> callback);

        /// <summary>
        /// 断开连接
        /// </summary>
        void Disconnect();

        /// <summary>
        /// 发送数据
        /// <param name="data">二进制数据</param>
        /// </summary>
        void Send(byte[] data);

        /// <summary>
        /// 设置超时时长
        /// <param name="connect">连接超时时间(单位：秒)</param>
        /// <param name="send">发送超时时间(单位：秒)</param>
        /// <param name="receive">接收超时时间(单位：秒)</param>
        /// </summary>
        void SetTimeoutSeconds(float connect, float send, float receive);

        /// <summary>
        /// 设置最大重连次数
        /// <param name="times">重连次数</param>
        /// </summary>
        void SetMaxReconnectTimes(int times);

        /// <summary>
        /// 监听数据接收回调
        /// <param name="callback">接收到的二进制数据回调</param>
        /// </summary>
        void AddReceiveListener(EventCallBack<ReceiveEventInfo>.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 移除数据接收回调
        /// <param name="callback">接收到的二进制数据回调</param>
        /// </summary>
        void RemoveReceiveListener(EventCallBack<ReceiveEventInfo>.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 监听数据发送结果回调
        /// <param name="callback">发送的结果回调(true:成功 false:失败)</param>
        /// </summary>
        void AddSendResultListener(EventCallBack<SendEventInfo>.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 移除数据发送结果回调
        /// <param name="callback">发送的结果回调(true:成功 false:失败)</param>
        /// </summary>
        void RemoveSendResultListener(EventCallBack<SendEventInfo>.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 监听重连回调
        /// <param name="callback">发送的结果回调(true:成功 false:失败)</param>
        /// </summary>
        void AddReconnectListener(EventCallBack<System.Action<bool>>.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 移除重连回调
        /// <param name="callback">发送的结果回调(true:成功 false:失败)</param>
        /// </summary>
        void RemoveReconnectListener(EventCallBack<System.Action<bool>>.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 监听断线回调
        /// <param name="callback">断线回调</param>
        /// </summary>
        void AddDisconnectListener(EventCallBack.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 移除断线回调
        /// <param name="callback">断线回调</param>
        /// </summary>
        void RemoveDisconnectListener(EventCallBack.CALL_FUNC_EVENT callback);

        /// <summary>
        /// 设置信息头长度和解析方法
        /// <param name="信息头长度">headerLength</param>
        /// <param name="写入解析方法">callbackParse</param>
        /// <param name="读取解析方法">callbackParse</param>
        /// </summary>
        void SetHeaderParse(int headerLength, System.Func<byte[], IHeaderInfo> callbackParse);

        /// <summary>
        /// 是否已成功连接
        /// </summary>
        bool IsConnected();
    }
}